<template>
    <container class="model-js">
        <toolbar>
            <div class="right" slot="right">
                <el-button size="mini" type="success" plain @click="templateDialog.visible = true">模板</el-button>
            </div>
        </toolbar>

        <el-card class="main">
            <operation>
                <el-button slot="right" type="text" size="mini" @click="goJsToHtml">前往 JS转HTML</el-button>
            </operation>

            <space height="20px"></space>

            <el-row type="flex" align="middle">
                <el-col :span="11">
                    <monaco-editor v-model="java" lang="java" height="75vh"></monaco-editor>
                </el-col>
                <el-col class="center" :span="2">
                    <el-button type="info" size="mini" @click="toJs">>></el-button>
                    <space height="20px"></space>
                    <el-button type="warning" size="mini" @click="toModel"><<</el-button>
                </el-col>
                <el-col :span="11">
                    <monaco-editor v-model="js" lang="javascript" height="75vh"></monaco-editor>
                </el-col>
            </el-row>
        </el-card>

        <!--dialog-->
        <template>
            <model-template-dialog
                    v-if="templateDialog.visible"
                    v-model="templateDialog.visible"
                    :default-template="templateDialog.defaultTemplate"
                    :cache-key="templateDialog.cacheKey">

            </model-template-dialog>
        </template>
    </container>
</template>

<script type="text/ecmascript-6">
  import Container from "../../components/common/Container";
  import Toolbar from "../../components/common/Toolbar";
  import MonacoEditor from "../../components/editor/MonacoEditor/index";
  import Space from "../../components/common/Space";
  import { BizError } from "../../utils/js/Error";
  import { defaultTemplate } from "./default-template";
  import { MODEL_JS } from "../../res/config-key";
  import ModelTemplateDialog from "../../components/template-dialog/ModelTemplateDialog";
  import * as Mustache from "mustache";
  import { local } from "../../utils/js/storage";
  import { firstToLower } from "../../utils/js/text";
  import convert from "./convertToJs";
  import Operation from "../../components/common/Operation";

  /**
   * @author 白雨浓
   * @date 2019/7/9 17:29
   *
   * 模型转JS
   **/
  export default {
    name: 'ModelJs',
    components: {Operation, ModelTemplateDialog, Space, MonacoEditor, Toolbar, Container},
    data() {
      return {
        templateDialog: {
          visible: false,
          defaultTemplate: defaultTemplate,
          cacheKey: MODEL_JS.TEMPLATE,
        },
        template: defaultTemplate,
        java: '',
        js: '',
        data: {},
      }
    },
    created() {
      const template = local.getItem(MODEL_JS.TEMPLATE);

      if (template) {
        this.template = template;
      }

      const model = this.$route.params['model'];
      if (model) {
        this.java = model;
      }
    },
    mounted() {

    },
    methods: {
      toJs() {

        const data = convert(this.java);

        const fields = data.fields.map(item => {
          const comment = item.comment ? item.comment.split('\n')[0] : null;
          return {...item, comment};
        });

        this.data = {
          ...data,
          fields
        };

        let result = Mustache.render(this.template, this.data);
        result = result.replace(/&lt;/g, "<");
        result = result.replace(/&gt;/g, ">");

        this.js = result;
      },
      handleModelName() {
        const MODEL_NAME_REG = /class (.*?)[{]/g;

        const res = MODEL_NAME_REG.exec(this.java);

        if (res) {
          return firstToLower(res[1].trim());
        }
      },
      handleVariables() {

        const start = this.java.indexOf('{');
        const end = this.java.lastIndexOf('}');
        const code = this.java.substring(start + 1, end);

        const PRIVATE = 'private';
        code.split('\n').forEach(line => {
          if (line.includes(';') && !line.trim().startsWith(PRIVATE)) {
            throw new BizError('注释中不得出现 \';\'')
          }
        });

        const blocks = code.split(';').filter(item => item.trim().length !== 0);

        const COMMENT_REG = /\/\*(\s|.)*?\*\//;
        const variables = [];
        for (const block of blocks) {
          const variable = {};
          const res = COMMENT_REG.exec(block);

          if (res) {
            const cs = res[0].split('\n').filter(item => {
              if (!item) {
                return false;
              }
              item = item.trim();
              return item.startsWith('*') && item !== '*/';
            });

            if (cs && cs[0]) {
              variable.comment = cs[0].trim().substring(1).trim();
            }
          }

          const codes = block.split('\n').filter(item => item.trim().startsWith(PRIVATE));

          if (codes) {
            const code = codes[0];
            const cs = code.trim().split(' ');

            variable.dataType = cs[1];
            variable.variable = cs[2];
          }

          variables.push(variable);
        }

        return variables;
      },
      toModel() {
        alert('尚不支持')
      },
      goJsToHtml() {
        this.$router.push({name: 'JsHtml', params: {js: this.js}})
      },
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
    .model-js {
    }

    .right {
        text-align right
        padding-right 10px
    }

    .main {
        width 98%
        margin 20px auto
    }

    .center {
        text-align center
    }
</style>
